home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 6 code / TCP / NewsWatcher / NW Source / Shared Code / Reusable Source / drawutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-14  |  12.8 KB  |  553 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     drawutil.c
  4.  
  5.     This reusable module contains miscellaneous drawing utility routines.
  6.     
  7.     Copyright © 1994-1995, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <Palettes.h>
  12.  
  13. #include "def.h"
  14. #include "drawutil.h"
  15.  
  16.  
  17.  
  18. /*----------------------------------------------------------------------------
  19.     HasColorQD 
  20.     
  21.     Check to see if color QuickDraw is available.
  22.     
  23.     Exit:    function result = true if we have color QD.
  24. ----------------------------------------------------------------------------*/
  25.  
  26. Boolean HasColorQD (void)
  27. {
  28.     OSErr err = noErr;
  29.     long quickdrawVersion;
  30.     static Boolean haveChecked = false;
  31.     static Boolean haveColorQD;
  32.     
  33.     if (!haveChecked) {
  34.         err = Gestalt(gestaltQuickdrawVersion, &quickdrawVersion);
  35.         haveColorQD = err == noErr && quickdrawVersion >= gestalt8BitQD;
  36.     }
  37.     return haveColorQD;
  38. }
  39.  
  40.  
  41.  
  42. /*----------------------------------------------------------------------------
  43.     SetPortTextStyle 
  44.     
  45.     Set the font, size, and style of the current port.
  46.             
  47.     Entry:    *style = text style record.
  48. ----------------------------------------------------------------------------*/
  49.  
  50. void SetPortTextStyle (TextStyle *style)
  51. {
  52.     TextFont(style->tsFont);
  53.     TextFace(style->tsFace);
  54.     TextSize(style->tsSize);
  55. }
  56.  
  57.  
  58.  
  59. /*----------------------------------------------------------------------------
  60.     GetPortTextStyle 
  61.     
  62.     Get the font, size, and style of the current port.
  63.             
  64.     Exit:    *style = text style record.
  65. ----------------------------------------------------------------------------*/
  66.  
  67. void GetPortTextStyle (TextStyle *style)
  68. {
  69.     style->tsFont = qd.thePort->txFont;
  70.     style->tsFace = qd.thePort->txFace;
  71.     style->tsSize = qd.thePort->txSize;
  72. }
  73.  
  74.  
  75.  
  76. /*----------------------------------------------------------------------------
  77.     DrawGrayRect 
  78.     
  79.     Draw a gray rectangle.
  80.             
  81.     Entry:    r = pointer to rectangle.
  82. ----------------------------------------------------------------------------*/
  83.  
  84. static pascal void DrawGrayRectOneDepth (short depth, short deviceFlags,
  85.     GDHandle targetDevice, long userData)
  86. {
  87.     RGBColor fg, bg, g;
  88.     
  89.     if (targetDevice != nil) {
  90.         GetForeColor(&fg);
  91.         GetBackColor(&bg);
  92.         g = fg;
  93.         if (GetGray(targetDevice, &bg, &g)) {
  94.             RGBForeColor(&g);
  95.             FrameRect((Rect*)userData);
  96.             RGBForeColor(&fg);
  97.             return;
  98.         }
  99.     }
  100.     PenPat(&qd.gray);
  101.     FrameRect((Rect*)userData);
  102.     PenPat(&qd.black);
  103. }
  104.  
  105. void DrawGrayRect (Rect *r)
  106. {
  107.     static DeviceLoopDrawingUPP upp = nil;
  108.  
  109.     if (upp == nil) upp = NewDeviceLoopDrawingProc(DrawGrayRectOneDepth);
  110.     DeviceLoop(qd.thePort->visRgn, upp, (long)r, 0);
  111. }
  112.  
  113.  
  114.  
  115. /*----------------------------------------------------------------------------
  116.     DrawGrayRoundRect 
  117.     
  118.     Draw a gray round rectangle.
  119.             
  120.     Entry:    r = pointer to rectangle.
  121.             ovalWidth = oval width.
  122.             ovalHeight = oval height.
  123. ----------------------------------------------------------------------------*/
  124.  
  125. typedef struct TDrawGrayRoundRectUserData {
  126.     Rect *r;
  127.     short ovalWidth;
  128.     short ovalHeight;
  129. } TDrawGrayRoundRectUserData;
  130.  
  131. static pascal void DrawGrayRoundRectOneDepth (short depth, short deviceFlags,
  132.     GDHandle targetDevice, long userData)
  133. {
  134.     RGBColor fg, bg, g;
  135.     TDrawGrayRoundRectUserData *ud;
  136.     
  137.     ud = (TDrawGrayRoundRectUserData*)userData;
  138.     if (targetDevice != nil) {
  139.         GetForeColor(&fg);
  140.         GetBackColor(&bg);
  141.         g = fg;
  142.         if (GetGray(targetDevice, &bg, &g)) {
  143.             RGBForeColor(&g);
  144.             FrameRoundRect(ud->r, ud->ovalWidth, ud->ovalHeight);
  145.             RGBForeColor(&fg);
  146.             return;
  147.         }
  148.     }
  149.     PenPat(&qd.gray);
  150.     FrameRoundRect(ud->r, ud->ovalWidth, ud->ovalHeight);
  151.     PenPat(&qd.black);
  152. }
  153.  
  154. void DrawGrayRoundRect (Rect *r, short ovalWidth, short ovalHeight)
  155. {
  156.     static DeviceLoopDrawingUPP upp = nil;
  157.     TDrawGrayRoundRectUserData ud;
  158.  
  159.     ud.r = r;
  160.     ud.ovalWidth = ovalWidth;
  161.     ud.ovalHeight = ovalHeight;
  162.     if (upp == nil) upp = NewDeviceLoopDrawingProc(DrawGrayRoundRectOneDepth);
  163.     DeviceLoop(qd.thePort->visRgn, upp, (long)&ud, 0);
  164. }
  165.  
  166.  
  167.  
  168. /*----------------------------------------------------------------------------
  169.     DrawColorPict 
  170.     
  171.     Draw a color picture.
  172.             
  173.     Entry:    colorID = resource id of color version of PICT.
  174.             bwID = resource id of black and white version of PICT.
  175.             r = pointer to rectangle.
  176. ----------------------------------------------------------------------------*/
  177.  
  178. typedef struct TDrawColorPictUserData {
  179.     short colorID;
  180.     short bwID;
  181.     Rect *r;
  182. } TDrawColorPictUserData;
  183.  
  184. static pascal void DrawColorPictOneDepth (short depth, short deviceFlags,
  185.     GDHandle targetDevice, long userData)
  186. {
  187.     TDrawColorPictUserData *ud;
  188.     
  189.     ud = (TDrawColorPictUserData*)userData;
  190.     if (targetDevice != nil && depth > 2) {
  191.         DrawPicture(GetPicture(ud->colorID), ud->r);
  192.     } else {
  193.         DrawPicture(GetPicture(ud->bwID), ud->r);
  194.     }
  195. }
  196.  
  197. void DrawColorPict (short colorID, short bwID, Rect *r)
  198. {
  199.     TDrawColorPictUserData ud;
  200.     static DeviceLoopDrawingUPP upp = nil;
  201.  
  202.     ud.colorID = colorID;
  203.     ud.bwID = bwID;
  204.     ud.r = r;
  205.     if (upp == nil) upp = NewDeviceLoopDrawingProc(DrawColorPictOneDepth);
  206.     DeviceLoop(qd.thePort->visRgn, upp, (long)&ud, 0);
  207. }
  208.  
  209.  
  210.  
  211. /*----------------------------------------------------------------------------
  212.     FillColorPoly 
  213.     
  214.     Fill a polygon in color.
  215.             
  216.     Entry:    poly = handle to polygon.
  217.             color = pointer to color.
  218.             pat = pattern.
  219. ----------------------------------------------------------------------------*/
  220.  
  221. typedef struct TFillColorPolyUserData {
  222.     PolyHandle poly;
  223.     RGBColor *color;
  224.     ConstPatternParam pat;
  225. } TFillColorPolyUserData;
  226.  
  227. static pascal void FillColorPolyOneDepth (short depth, short deviceFlags,
  228.     GDHandle targetDevice, long userData)
  229. {
  230.     TFillColorPolyUserData *ud;
  231.     RGBColor fgColor;
  232.     
  233.     ud = (TFillColorPolyUserData*)userData;
  234.     if (targetDevice != nil && depth > 2) {
  235.         GetForeColor(&fgColor);
  236.         RGBForeColor(ud->color);
  237.         FillPoly(ud->poly, ud->pat);
  238.         RGBForeColor(&fgColor);
  239.     }
  240. }
  241.  
  242. void FillColorPoly (PolyHandle poly, RGBColor *color, ConstPatternParam pat)
  243. {
  244.     TFillColorPolyUserData ud;
  245.     static DeviceLoopDrawingUPP upp = nil;
  246.  
  247.     ud.poly = poly;
  248.     ud.color = color;
  249.     ud.pat = pat;
  250.     if (upp == nil) upp = NewDeviceLoopDrawingProc(FillColorPolyOneDepth);
  251.     DeviceLoop(qd.thePort->visRgn, upp, (long)&ud, 0);
  252. }
  253.  
  254.  
  255.  
  256. /*----------------------------------------------------------------------------
  257.     FrameGrayPoly 
  258.     
  259.     Frame a polygon in gray.
  260.             
  261.     Entry:    poly = handle to polygon.
  262.     
  263.     On B&W monitors, framing in gray doesn't work very well, so in that case
  264.     we frame in black.
  265. ----------------------------------------------------------------------------*/
  266.  
  267. static pascal void FrameGrayPolyOneDepth (short depth, short deviceFlags,
  268.     GDHandle targetDevice, long userData)
  269. {
  270.     RGBColor fg, bg, g;
  271.     
  272.     if (targetDevice != nil) {
  273.         GetForeColor(&fg);
  274.         GetBackColor(&bg);
  275.         g = fg;
  276.         if (GetGray(targetDevice, &bg, &g)) {
  277.             RGBForeColor(&g);
  278.             FramePoly((PolyHandle)userData);
  279.             RGBForeColor(&fg);
  280.             return;
  281.         }
  282.     }
  283.     FramePoly((PolyHandle)userData);
  284. }
  285.  
  286. void FrameGrayPoly (PolyHandle poly)
  287. {
  288.     static DeviceLoopDrawingUPP upp = nil;
  289.  
  290.     if (upp == nil) upp = NewDeviceLoopDrawingProc(FrameGrayPolyOneDepth);
  291.     DeviceLoop(qd.thePort->visRgn, upp, (long)poly, 0);
  292. }
  293.  
  294.  
  295.  
  296. /*----------------------------------------------------------------------------
  297.     FillColorRect 
  298.     
  299.     Fill a rectangle in color.
  300.             
  301.     Entry:    r = pointer to rectangle.
  302.             color = pointer to color to use if depth > 2.
  303.             pat = B&W pattern to use if depth <= 2.
  304. ----------------------------------------------------------------------------*/
  305.  
  306. typedef struct TFillColorRectUserData {
  307.     Rect *r;
  308.     RGBColor *color;
  309.     ConstPatternParam pat;
  310. } TFillColorRectUserData;
  311.  
  312. static pascal void FillColorRectOneDepth (short depth, short deviceFlags,
  313.     GDHandle targetDevice, long userData)
  314. {
  315.     TFillColorRectUserData *ud;
  316.     RGBColor fgColor;
  317.     
  318.     ud = (TFillColorRectUserData*)userData;
  319.     if (targetDevice != nil && depth > 2) {
  320.         GetForeColor(&fgColor);
  321.         RGBForeColor(ud->color);
  322.         PaintRect(ud->r);
  323.         RGBForeColor(&fgColor);
  324.     } else {
  325.         FillRect(ud->r, ud->pat);
  326.     }
  327. }
  328.  
  329. void FillColorRect (Rect *r, RGBColor *color, ConstPatternParam pat)
  330. {
  331.     TFillColorRectUserData ud;
  332.     static DeviceLoopDrawingUPP upp = nil;
  333.  
  334.     if (upp == nil)
  335.         upp = NewDeviceLoopDrawingProc(FillColorRectOneDepth);
  336.     ud.r = r;
  337.     ud.color = color;
  338.     ud.pat = pat;
  339.     DeviceLoop(qd.thePort->visRgn, upp, (long)&ud, 0);
  340. }
  341.  
  342.  
  343.  
  344. /*----------------------------------------------------------------------------
  345.     FillGrayRect 
  346.     
  347.     Fill a rectangle with gray.
  348.             
  349.     Entry:    r = pointer to rectangle.
  350. ----------------------------------------------------------------------------*/
  351.  
  352. static pascal void FillGrayRectOneDepth (short depth, short deviceFlags,
  353.     GDHandle targetDevice, long userData)
  354. {
  355.     Rect *r;
  356.     RGBColor fg, bg, g;
  357.     
  358.     r = (Rect*)userData;
  359.     if (targetDevice != nil) {
  360.         GetForeColor(&fg);
  361.         GetBackColor(&bg);
  362.         g = fg;
  363.         if (GetGray(targetDevice, &bg, &g)) {
  364.             RGBForeColor(&g);
  365.             PaintRect(r);
  366.             RGBForeColor(&fg);
  367.             return;
  368.         }
  369.     }
  370.     FillRect(r, &qd.gray);
  371. }
  372.  
  373. void FillGrayRect (Rect *r)
  374. {
  375.     static DeviceLoopDrawingUPP upp = nil;
  376.  
  377.     if (upp == nil)
  378.         upp = NewDeviceLoopDrawingProc(FillGrayRectOneDepth);
  379.     DeviceLoop(qd.thePort->visRgn, upp, (long)r, 0);
  380. }
  381.  
  382.  
  383.  
  384. /*----------------------------------------------------------------------------
  385.     ComplementRgn 
  386.     
  387.     Complement a QuickDraw region.
  388.             
  389.     Entry:    rgn = handle to region.
  390.     
  391.     Exit:    Region complemented.
  392. ----------------------------------------------------------------------------*/
  393.  
  394. void ComplementRgn (RgnHandle rgn)
  395. {
  396.     static RgnHandle bigRgn = nil;
  397.     
  398.     if (bigRgn == nil) {
  399.         bigRgn = NewRgn();
  400.         SetRectRgn(bigRgn, -0x7fff, -0x7fff, 0x7fff, 0x7fff);
  401.     }
  402.     DiffRgn(bigRgn, rgn, rgn);
  403. }
  404.  
  405.  
  406.  
  407. /*----------------------------------------------------------------------------
  408.     LocalToGlobalRect 
  409.     
  410.     Convert a rectangle from local to global coordinates.
  411.             
  412.     Entry:    r = pointer to rectangle.
  413. ----------------------------------------------------------------------------*/
  414.  
  415. void LocalToGlobalRect (Rect *r)
  416. {
  417.     LocalToGlobal((Point*)&r->top);
  418.     LocalToGlobal((Point*)&r->bottom);
  419. }
  420.  
  421.  
  422.  
  423. /*----------------------------------------------------------------------------
  424.     GlobalToLocalRect 
  425.     
  426.     Convert a rectangle from global to local coordinates.
  427.             
  428.     Entry:    r = pointer to rectangle.
  429. ----------------------------------------------------------------------------*/
  430.  
  431. void GlobalToLocalRect (Rect *r)
  432. {
  433.     GlobalToLocal((Point*)&r->top);
  434.     GlobalToLocal((Point*)&r->bottom);
  435. }
  436.  
  437.  
  438.  
  439. /*----------------------------------------------------------------------------
  440.     LocalToGlobalRgn 
  441.     
  442.     Convert a region from local to global coordinates.
  443.             
  444.     Entry:    rgn = handle to region.
  445. ----------------------------------------------------------------------------*/
  446.  
  447. void LocalToGlobalRgn (RgnHandle rgn)
  448. {
  449.     Point where;
  450.     
  451.     SetPt(&where, 0, 0);
  452.     LocalToGlobal(&where);
  453.     OffsetRgn(rgn, where.h, where.v);
  454. }
  455.  
  456.  
  457.  
  458. /*----------------------------------------------------------------------------
  459.     GlobalToLocalRgn 
  460.     
  461.     Convert a region from global to local coordinates.
  462.             
  463.     Entry:    rgn = handle to region.
  464. ----------------------------------------------------------------------------*/
  465.  
  466. void GlobalToLocalRgn (RgnHandle rgn)
  467. {
  468.     Point where;
  469.     
  470.     SetPt(&where, 0, 0);
  471.     LocalToGlobal(&where);
  472.     OffsetRgn(rgn, -where.h, -where.v);
  473. }
  474.  
  475.  
  476.  
  477. /*----------------------------------------------------------------------------
  478.     GetFontNumber 
  479.     
  480.     Get the font number corresponding to a font name (adapted from Think Ref).
  481.             
  482.     Entry:    fontName = font name.
  483.     
  484.     Exit:    function result = true if font exists.
  485.             *fontNum = font number.
  486.             
  487.     If the font doesn't exist, the font number is set to Monaco, or to 
  488.     applFont if Monaco also doesn't exist.
  489. ----------------------------------------------------------------------------*/
  490.  
  491. Boolean GetFontNumber (Str255 fontName, short *fontNum)
  492. {
  493.     Str255 systemFontName;
  494.  
  495.     GetFNum(fontName, fontNum);
  496.     if (*fontNum != 0) return true;
  497.     GetFontName(0, systemFontName);
  498.     if (EqualString(fontName, systemFontName, false, false)) return true;
  499.     GetFNum("\pMonaco", fontNum);
  500.     if (*fontNum == 0) *fontNum = applFont;
  501.     return false;
  502. }
  503.  
  504.  
  505.  
  506. /*----------------------------------------------------------------------------
  507.     GetFontLineHeight 
  508.     
  509.     Get the line height in pixels of a window font.
  510.             
  511.     Entry:    wind = pointer to window.
  512.     
  513.     Exit:    function result = line height.
  514. ----------------------------------------------------------------------------*/
  515.  
  516. short GetFontLineHeight (WindowPtr wind)
  517. {
  518.     FontInfo fInfo;
  519.     GrafPtr port;
  520.  
  521.     GetPort(&port);
  522.     SetPort(wind);
  523.     GetFontInfo(&fInfo);
  524.     SetPort(port);
  525.     return fInfo.ascent + fInfo.descent + fInfo.leading;
  526. }
  527.  
  528.  
  529.  
  530. /*----------------------------------------------------------------------------
  531.     OutlineRegion 
  532.     
  533.     Change a region into a tracing of its border which is appropriate 
  534.     for normal dragging.
  535.             
  536.     Entry:    theRgn = handle to region.
  537.     
  538.     Exit:    Region changed to outline of region.
  539.     
  540.     From Apple "HFS Drag Sample" sample code.
  541. ----------------------------------------------------------------------------*/
  542.  
  543. void OutlineRegion (RgnHandle theRgn)
  544. {
  545.     RgnHandle tempRgn;
  546.     
  547.     tempRgn = NewRgn();
  548.     CopyRgn(theRgn, tempRgn);
  549.     InsetRgn(tempRgn, 1, 1);
  550.     DiffRgn(theRgn, tempRgn, theRgn);
  551.     DisposeRgn(tempRgn);
  552. }
  553.